(Lab_Event > index_OK.html、index_2.html)
(1)製作元件Toggle增加屬性dataList、並更改dataList[0]
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {
//兩個屬性isToggleOn、dataList
isToggleOn: true,
dataList: [
{ name: "Jina" },
{},
{}] };
this.state.dataList[0].name = "other peoplo"; //1.此處網頁跑完前已變更
}
(2)預告執行程式時alert呼叫 1.data 2.dataList[0].name 3."Button clicked,顯示變更setState
doClick = (e, data) => {
alert(data);
alert(this.state.dataList[0].name);
this.setState({ //2.顯示變更網頁使用後屬性
isToggleOn: !this.state.isToggleOn,
});
alert("Button clicked.");
// this.setState({}); //2.顯示變更網頁使用後屬性
};
(3)render 案到按鈕回傳
render() {
return (
<button
// 滑鼠點擊事件,data undefined,因為沒給值
onClick={this.doClick}
// 執行此處 okkk > 1000 > other peoplo > Button clicked
// 執行順序 alert("okkk")後 將值傳入(e,data)跑doClick
onMouseLeave={(e) => {
alert("okkk");
{
this.doClick(e, 1000);
}
}}
className="btn btn-outline-success"
>
{this.state.isToggleOn ? "ON" : "OFF"}
</button>
);
}
Q:為何dataList[0].name改為"other peoplo"沒有setState亦變更顯示?
A:因setState作用為網頁跑完後,變更屬性時顯示變更
但此處網頁跑完前dataList[0].name已變更完畢
(Lab_Event > index_OK.html)
doClick = (e) => {
// console.log(this);
this.setState({
isToggleOn: !this.state.isToggleOn,
});
};
不必要,仍可執行,但增加可以看React包裝過的event事件
但沒有e也可用使用event看event事件
doClick = (e) => {
console.log(this); //Toggle {props: {…}....
console.log(event); //此event 是傳統js 的event事件
console.log(e); //doClick = (e)沒有e會無法顯示,此e傳入的是React 包裝過的event事件
this.setState({
isToggleOn: !this.state.isToggleOn,
});
alert("Button clicked.");
};
(Lab_Event > index_OK.html)
onMouseLeave
render() {
return (
<button onMouseLeave={this.doClick} className="btn btn-outline-success">
{this.state.isToggleOn ? "ON" : "OFF"}
</button>
);
}
onClick
render() {
return (
<button onClick={this.doClick} className="btn btn-outline-success">
{this.state.isToggleOn ? "ON" : "OFF"}
</button>
);
}
(Lab_Event > ClassroomDemo.html、demo.html)
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Spread_syntax
(1)原本沒有使用...時
var dataList = [10, 20, 30];
var newDataList = [];
for (let i = 0; i < dataList.length; i++) {
var item = dataList[i]; //1.取出一個[0][1][2]
newDataList.push(item); //2.放進來
}
newDataList.push(40); //3. [3]:40
debug.innerText = newDataList.join(" | "); //10 | 20 | 30 | 40
(2)使用...
var dataList = [10, 20, 30];
//複製dataList[10, 20, 30]的內容 再把他解壓縮展開
var newDataList = [...dataList, 40];
debug.innerText = newDataList.join(" | "); //10 | 20 | 30 | 40
兩種結果相同,但...較簡潔
其他範例
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = { isToggleOn: true };
}
doClick = (e, currentToggle) => {
//1.把舊狀態Toggle下的state拿出來,成立一個新狀態
let newState = { ...this.state };
//2.新狀態的屬性
newState.isToggleOn = !currentToggle;
//3.交給setState 顯示改變新狀態的屬性
this.setState(newState);
};
(JavaScript > 05_array> Array_20_map.html)
var data = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6];
//map將陣列内客依序傳入,但需retur做回傳,否則map跑完,dataList的陣内容是空的
var dataList = data.map(function (item) {
return item + 10;
}); //將陣列內容依序傳入 並+10
箭頭函式 (只回傳一值 => 無須{}及return)
var dataList = data.map((aaa) => aaa + 10); //將陣列內容依序傳入 並回傳+10
同方法4.,非 => 寫法
var dataList = data.map(function (aaa) {
return aaa + 10;
});
(Lab_Props > ClassroomDemo_a.html)
class extends React.Component {
render() {
return <h3>{this.props.name}</h3>;
}
}
const expertList = [
{ id: 1, name: "Jeter0.5" },
{ id: 2, name: "Messi0.5" },
{ id: 3, name: "Jordan0.5" },
{ id: 4, name: "QQQ0.5" },
];
const element3 = (
<div>
{expertList.map((expert) => (
<Welcome name={expert.name} /> //Welcome元件的expertList顯示
))}
<Welcome name="Jeter" />
<Welcome name="Messi" />
<Welcome name="Jordan" />
</div>
);
ReactDOM.render(element3, document.getElementById("root"));
注意this.state.expertList必要,才能指定「這裡」,否則會抓到外面const expertList[]
並且return element5
class App extends React.Component {
constructor() {
super();
this.state = {
expertList: [
{ id: 1, name: "Jeter" },
{ id: 2, name: "Messi" },
{ id: 3, name: "Jordan" },
],
};
}
// 把element4搬進來製作element5
render() {
const element5 = (
// this.state.expertList必要,才能指定「這裡」,否則會抓到外面const expertList[]
<div>
{this.state.expertList.map((expert) => (
<Welcome name={expert.name} key={expert.id} />
))}
<Welcome name="Jeter" />
<Welcome name="Messi" />
<Welcome name="Jordan" />
</div>
);
// return
return element5;
}
}
class App2 extends React.Component {
constructor() {
super();
this.state = {
expertList: [
{ id: 1, name: "Jeter.App2" },
{ id: 2, name: "Messi.App2" },
{ id: 3, name: "Jordan.App2" },
],
};
}
// 3.製作onClick事件
doClick = () => {
//新式寫法 有改變就變更顯示
this.state.expertList[0].name = this.state.expertList[0].name.toUpperCase();
//toUpperCase轉大寫
this.setState({}); //網頁跑完後,變更時顯示變更屬性
};
render() {
// 1. 此處清空,顯示搬到return
// const element6 = (
// <div>
// {this.state.expertList.map((expert) => (
// <Welcome name={expert.name} key={expert.id} />
// ))}
// <Welcome name="Jeter.element6" />
// <Welcome name="Messi.element6" />
// <Welcome name="Jordan.element6" />
// </div>
// );
//2. return 製作按鈕 並 製作onClick事件
return (
<div>
<button class="btn btn-success" onClick={this.doClick}>
轉成大寫的按鈕
</button>
{this.state.expertList.map((expert) => (
<Welcome name={expert.name} key={expert.id} />
))}
</div>
);
}
}
ReactDOM.render(<App2 />, document.getElementById("root4"));
// 2.App元件state屬性放expertList
class App extends React.Component {
state = {
expertList: [
{ id: 1, name: "Jeter" },
{ id: 2, name: "Messi" },
{ id: 3, name: "Jordan" },
],
};
// 3. 製作f,toUpperCase並且可以跑完網頁後,屬性變更時隨時變更setState
doClick = (e) => {
let newState = { ...this.state };
newState.expertList[0].name = newState.expertList[0].name.toUpperCase();
this.setState(newState);
};
// 12.製作刪除資料的f
// 15.製作成箭頭函式
doDelete = (e, id) => {
alert("我負責刪除資料" + id);
alert(e + id);
//16.執行刪除的f
var newState = { ...this.state };
newState.expertList = newState.expertList.filter((expert) => expert.id != id);
this.setState(newState);
};
// 4.回傳網頁內容讓button綁onClick滑鼠事件執行doClick
// 5.內含f,App屬性內expertList.map方法,將[]一個一個return製作成Welcome物件(9.12.)
render() {
return (
<div className="container">
<button className="btn btn-outline-success" onClick={this.doClick}>
Jeter toUpperCase
</button>
{this.state.expertList.map((expert) => (
// 9.key是react才有的,所以多製作id={expert.id}
// 12.製作刪除資料的屬性onDelete={this.doDelete}
<Welcome name={expert.name} key={expert.id} id={expert.id} onDelete={this.doDelete} />
))}
</div>
// Welcome物件的name = Jeter id=1
);
}
}
// 6.Welcome回傳props屬性的name(5.給的)
class Welcome extends React.Component {
// 8.製作onClick事件內的f handlerDelectButtonClick
handlerDelectButtonClick = (e) => {
alert(this.props.key); // 10.抓不到react自己創的 所以做一個id
alert(this.props.name);
alert(this.props.id); // 11.抓到了
this.props.onDelete(); //呼叫alert("我負責刪除資料"); > 此處沒給值
this.props.onDelete(this.props.id); //13.呼叫alert("我負責刪除資料 + id"); > 此處沒給值
this.props.onDelete(e, this.props.id); //14.傳兩個值給onDelete() 並執行;
};
render() {
// JSX 外面一定要包東西,把每個東西包起來<div> 或使用 <React.Fragment>
//return()必要,避免return;
return (
// 7.新增<button>及其內onClick事件
<h3>
{this.props.name} {" "}
<button onClick={this.handlerDelectButtonClick} class="btn btn-outline-danger">
×
</button>
</h3>
);
}
}
// 1.製做App元件
// 輸出到root
ReactDOM.render(<App></App>, document.getElementById("root"));
class Welcome extends React.Component {
render() {
//return()必要,避免return;
return (
//方法1.
// <h3>{this.props.name}</h3>
//方法2.
// <div>
// <h3>{this.props.name}</h3>我是想增加的內容
// </div>
//方法3.
<React.Fragment>
<h3>{this.props.name}</h3>我是想增加的內容
</React.Fragment>
);
}
}
(Lab_useState > index_0.html)
//1. function元件製作
function App() {
// 2.解構賦值 let[變數, 方法]
// useState()設定初值count=變數,setCount=方法 ,傳回陣列[]
let [count, setCount] = React.useState(50); //count=50
const doIncrement = () => {
// 4.onClick事件的f
alert("OK");
count += 1; // 5. +1 但不會顯示
console.log(Date());
console.log(count);
console.log(setCount);
setCount(count + 1); // 6. +1 setCount似setState顯示網頁跑完之後的變更
};
return (
// 3.新增buttonu並增加onClick事件
<React.Fragment>
<h3>count:{count}</h3>
<button onClick={doIncrement} className="btn btn-outline-success">
一直加上去
</button>
</React.Fragment>
);
}
連續使用setCount會錯誤
用=>讓程式可以同時進行而加二
const handleIncrement = () => {
// 連續使用setCount會錯誤
// 加一? 還是加二? 加一 解決如下
// setCount(count + 1);
// setCount(count + 1);
// --------------------
// 加一? 還是加二? 加二
// 用=>讓程式可以同時進行而加二
setCount((previous) => previous + 1);
setCount((previous) => previous + 1);
};
(Lab_useState > demo02.html)
[]給[] 需照順序
var datalist = [10, 20];
// var x = datalist[0];
// var y = datalist[1];
var [x, y] = datalist; //解構賦值 [x, y] = [10, 20]
alert(x + " " + y);
{}給{} 需同名資料
var player = {
firstName: "Jeremy",
LastNasme: "Lin",
unmber: 7,
};
// 方法1.
// var LastNasme = player.LastNasme;
// var firstName = player.firstName;
// 方法2.使用解構賦值
var { LastNasme, firstName } = player;
alert(LastNasme);
alert(firstName);
變更顯示完之後,想做的事件都放在useEffect裡面
(Lab_useEffect > index_1_useEffect.html)
// 2.製作App元件
function App() {
const [count, setCount] = React.useState(0);
//const [count2, setCount2] = React.useState(0);
// 4.變更顯示count + 1
const doClick = () => {
setCount(count + 1);
};
// 5.變更顯示完之後,想做的事件都放在useEffect裡面
React.useEffect(() => {
document.title = `Click count: ${count}`; //網頁名稱變更
});
//}, [count])
return (
// 3.按鈕掛上onClick事件,按下按鈕觸發doClick
<div>
<button onClick={doClick}>Click count: {count}</button>
</div>
);
}
// 1.render
ReactDOM.render(<App />, document.getElementById("root"));
useEffect內的為什麼不放在doClick內? ********************************重點
因為怕程式沒跑到(連續使用setCount會錯誤)前有範例